﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Metadata.Edm;
using Framework.DSL;
using Microsoft.VisualStudio.Modeling;

namespace TesteT4
{
    public class AuxiliarTemplate
    {
        string variavelNamespaceMensagem = "Atacadao.Comum.Recursos.Mensagens";
        string variavelNamespaceTemporario = "Atacadao.DB";

        /// <summary>
        /// Cria um atributo para o diagrama de decoradores da entidade de classe.
        /// </summary>
        /// <param name="edmProperty"></param>
        /// <param name="navigations"></param>
        /// <returns></returns>
        public DropDownlist CriarAtributoDropDown(Store store, EdmProperty edmProperty, ReadOnlyMetadataCollection<NavigationProperty> navigations)
        {
            DropDownlist retorno = null;
            MetadataTools ef = new MetadataTools(this);


            foreach (var navProperty in navigations)
            {

                if (((AssociationType)navProperty.RelationshipType).ReferentialConstraints.Count == 0)
                {
                    continue;
                }

                EdmProperty propriedadePai = ef.GetCorrespondingPrincipalProperty(navProperty, edmProperty);

                if (propriedadePai != null)
                {
                    string codigo = string.Empty;
                    string descricao = string.Empty;

                    foreach (EdmProperty item in propriedadePai.DeclaringType.Members.Where(p => p.TypeUsage.EdmType is PrimitiveType))
                    {
                        if (ef.IsKey(item))
                        {
                            codigo = item.Name;
                        }
                        else if (item.TypeUsage.EdmType.Name == PrimitiveTypeKind.String.ToString())
                        {
                            descricao = item.Name;
                        }

                        if (!string.IsNullOrEmpty(codigo) && !string.IsNullOrEmpty(descricao)) { break; }
                    }

                    retorno = new DropDownlist(store);
                    retorno.NomeEntidade = propriedadePai.DeclaringType.FullName.Replace(variavelNamespaceTemporario + ".", "");
                    retorno.CampoCodigo = codigo;
                    retorno.CampoTexto = descricao;
                    retorno.TextoNaoSelecionado = "Selecione";

                }

            }

            return retorno;
        }

        /// <summary>
        /// Cria classe representando do tipo de dado.
        /// </summary>
        /// <param name="edmProperty"></param>
        /// <returns></returns>
        public TipoDados CriarAtributoTipoDados(Store store, EdmProperty edmProperty)
        {
            TipoDados retorno = null;
            MetadataTools ef = new MetadataTools(this);
            TipoDadoCampo tipo = TipoDadoCampo.Texto;
            int tamanho = 0;
            int parteDecimal = 0;

            if (ef.IsKey(edmProperty))
            {
                tipo = TipoDadoCampo.Chave;
            }
            else if (edmProperty.TypeUsage.EdmType.Name == PrimitiveTypeKind.Int32.ToString() ||
                edmProperty.TypeUsage.EdmType.Name == PrimitiveTypeKind.Int16.ToString() ||
                edmProperty.TypeUsage.EdmType.Name == PrimitiveTypeKind.Int64.ToString() ||
                edmProperty.TypeUsage.EdmType.Name == PrimitiveTypeKind.Byte.ToString())
            {
                tipo = TipoDadoCampo.Numero;
            }
            else if (edmProperty.TypeUsage.EdmType.Name == PrimitiveTypeKind.Decimal.ToString() ||
                edmProperty.TypeUsage.EdmType.Name == PrimitiveTypeKind.Double.ToString())
            {
                tipo = TipoDadoCampo.Decimal;


                if (edmProperty.TypeUsage.Facets.Contains("Precision"))
                {
                    tamanho = int.Parse(edmProperty.TypeUsage.Facets["Precision"].Value.ToString());
                }

                if (edmProperty.TypeUsage.Facets.Contains("Scale"))
                {
                    parteDecimal = int.Parse(edmProperty.TypeUsage.Facets["Scale"].Value.ToString());
                }
            }
            else if (edmProperty.TypeUsage.EdmType.Name == PrimitiveTypeKind.Boolean.ToString())
            {
                tipo = TipoDadoCampo.Boolean;
            }
            else if (edmProperty.TypeUsage.EdmType.Name == PrimitiveTypeKind.String.ToString())
            {
                
                tamanho = 0;

                if (edmProperty.TypeUsage.Facets.Contains("MaxLength") && edmProperty.TypeUsage.Facets["MaxLength"].Value != null)
                {
                    int.TryParse(edmProperty.TypeUsage.Facets["MaxLength"].Value.ToString(), out tamanho);
                }

                if (tamanho == 0) tipo = TipoDadoCampo.Multiline;

                if (tamanho > 100) tipo = TipoDadoCampo.Multiline;
                else tipo = TipoDadoCampo.Texto;

            }
            else if (edmProperty.TypeUsage.EdmType.Name == PrimitiveTypeKind.DateTime.ToString())
            {
                tipo = TipoDadoCampo.Date;
            }

            retorno = new TipoDados(store);
            retorno.Campo = edmProperty.Name;
            retorno.TipoDado =  tipo;
            retorno.Tamanho = tamanho;
            retorno.Precisao = parteDecimal;

            return retorno; 
        }

        public string EscreverAtributoMaiorQueAtributo(MaiorIgualQueAttribute atr)
        {
           return string.Format("[MaiorQue(\"{0}\",TipoComparacao.{1})]",atr.Campo2,atr.TipoComparacao.ToString());
        }

        public string EscreverAtributoMenorQueAtributo(MaiorIgualQueAttribute atr)
        {
            return string.Format("[MenorQue(\"{0}\",TipoComparacao.{1})]", atr.Campo2, atr.TipoComparacao.ToString());
        }

        public string EscreverAtributoMaiorIgualQueAtributo(MaiorIgualQueAttribute atr)
        {
            return string.Format("[MaiorIgualQue(\"{0}\",TipoComparacao.{1})]", atr.Campo2, atr.TipoComparacao.ToString());
        }

        public string EscreverAtributoMenorIgualQueAtributo(MaiorIgualQueAttribute atr)
        {
            return string.Format("[MenorIgualQue(\"{0}\",TipoComparacao.{1})]", atr.Campo2, atr.TipoComparacao.ToString());
        }

        public string EscreverAtributoCPF(CpfCnpjValidator atr)
        {
            return string.Format("[CpfCnpjValidator(TipoValidacaoCPFCNPJ.{0})]", atr.Tipo.ToString().ToUpper());
        }

        public string EscreverAtributoMascara(MascaraAttribute atr)
        {
            return string.Format("[Mascara(\"{0}\")]", atr.Mascara);
        }

        public string EscreverAtributoDisplayName(DisplayName atr)
        {
            return string.Format("[Display(\"{0}\")]", atr.Exibicao);
        }

        public string EscreverAtributoObrigatorio(Obrigatorio obr)
        {
            MetadataTools ef = new MetadataTools(this);

            return string.Format("[Required(AllowEmptyStrings=false, ErrorMessageResourceType=(typeof({0})), ErrorMessageResourceName=\"A007\")]", variavelNamespaceMensagem);

        }

        public string EscreverAtributoTipoDado(TipoDados tipo, DropDownlist dropdownlist)
        {

            string templateStr = "[DataType(\"{0}\", ErrorMessageResourceType=(typeof({1})), ErrorMessageResourceName=\"A005\")]";
            string template = "[DataType({0}, ErrorMessageResourceType=(typeof({1})), ErrorMessageResourceName=\"A005\")]";

            string strTamanho = string.Empty;

            MetadataTools ef = new MetadataTools(this);

            if (dropdownlist != null)
            {
                return string.Format("[DropDownList(\"{0}\", \"{1}\", \"{2}\", \"{3}\")]",dropdownlist.NomeEntidade, dropdownlist.CampoTexto, dropdownlist.CampoCodigo, dropdownlist.TextoNaoSelecionado);
            }


            switch (tipo.TipoDado)
            {
                case TipoDadoCampo.Chave:
                    return string.Format(templateStr, "Codigo", variavelNamespaceMensagem);
                case TipoDadoCampo.Numero:
                    return string.Format(templateStr, "Numero", variavelNamespaceMensagem);
                case TipoDadoCampo.Decimal:
                    return string.Format("[Decimal(Tamanho={0}, Precisao={1})]", tipo.Tamanho, tipo.Precisao);
                case TipoDadoCampo.Boolean:
                    return string.Format(templateStr, "Boolean", variavelNamespaceMensagem);
                case TipoDadoCampo.Multiline:

                    strTamanho = string.Format("[StringLength({0}, ErrorMessageResourceType=(typeof({1})), ErrorMessageResourceName=\"A006\")]", tipo.Tamanho, variavelNamespaceMensagem);

                    return String.Concat(string.Format(template, "DataType.MultilineText", variavelNamespaceMensagem), strTamanho);

                  case TipoDadoCampo.Texto:
                   
                    strTamanho = string.Format("[StringLength({0}, ErrorMessageResourceType=(typeof({1})), ErrorMessageResourceName=\"A006\")]", tipo.Tamanho, variavelNamespaceMensagem);

                    return String.Concat(string.Format(template, "DataType.Text", variavelNamespaceMensagem), strTamanho);

                case TipoDadoCampo.Date:
                    return string.Concat(string.Format(template, "DataType.Date", variavelNamespaceMensagem), " [DisplayFormat(DataFormatString=\"{0:dd/MM/yyyy}\", ApplyFormatInEditMode=true)]");
                case TipoDadoCampo.DateTime:
                    return string.Concat(string.Format(template, "DataType.DateTime", variavelNamespaceMensagem), " [DisplayFormat(DataFormatString=\"{0:dd/MM/yyyy}\", ApplyFormatInEditMode=true)]");
                default:
                    break;
            }

            

            return "";
        }

        public bool TemDropDownlist(EdmProperty edmProperty, ReadOnlyMetadataCollection<NavigationProperty> navigations)
        {
            MetadataTools ef = new MetadataTools(this);
            bool retorno = false;

            foreach (var navProperty in navigations)
            {

                if (((AssociationType)navProperty.RelationshipType).ReferentialConstraints.Count == 0)
                {
                    continue;
                }

                EdmProperty propriedadePai = ef.GetCorrespondingPrincipalProperty(navProperty, edmProperty);

                if (propriedadePai != null)
                {
                    retorno = true;
                }

            }

            return retorno;
        }

       
    }
}
